package org.example.business.endpoint.http.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.FileUpload;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import lombok.extern.slf4j.Slf4j;
import org.example.business.endpoint.http.event.message.HttpMsg;
import org.example.business.endpoint.http.event.message.HttpReq;
import org.example.business.endpoint.http.event.message.HttpRsp;
import org.example.util.ArrayUtil;

@Slf4j
public class HttpMsgDecoder extends SimpleChannelInboundHandler<HttpObject> {

    private HttpRequest httpRequest;
    private HttpPostRequestDecoder postRequestDecoder;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject httpObject) throws Exception {
        log.info("解码消息 {}", httpObject);

        if(httpObject instanceof HttpRequest){

            HttpRequest request = (HttpRequest)httpObject;

            if(HttpMethod.GET.equals(request.method())){
                channelRead(ctx, transformRequest(ctx, request));
                return;

            }

            if(HttpMethod.POST.equals(request.method())){
                httpRequest = request;
                postRequestDecoder = new HttpPostRequestDecoder(request);

            }

        }

        if(httpObject instanceof HttpContent && null != postRequestDecoder){
            HttpContent content = (HttpContent)httpObject;
            postRequestDecoder.offer(content);

            if(content instanceof LastHttpContent){

                HttpReq httpReq = transformRequest(ctx, httpRequest, postRequestDecoder);

                postRequestDecoder.destroy();

                channelRead(ctx, httpReq);

            }

        }

    }

    private HttpMsg transformRequest(ChannelHandlerContext ctx, HttpRequest httpRequest){



        HttpReq httpReq = new HttpReq();

        assignMessageId(httpReq);
        transportMetaInfo(httpReq, httpRequest);

        QueryStringDecoder queryStringDecoder = new QueryStringDecoder(httpRequest.uri());
        queryStringDecoder.parameters().forEach((key, values)->{
            httpReq.addParam(key, ArrayUtil.join2String(values.toArray(new String[]{}), ";"));

        });

        HttpMsg httpMsg = new HttpMsg();

        httpMsg.setHttpReq(httpReq);
        httpMsg.setHttpRsp(new HttpRsp());

        return httpMsg;

    }

    private HttpReq transformRequest(ChannelHandlerContext ctx, HttpRequest httpRequest, HttpPostRequestDecoder postRequestDecoder){

        HttpReq httpReq = new HttpReq();

        assignMessageId(httpReq);
        transportMetaInfo(httpReq, httpRequest);

        postRequestDecoder.getBodyHttpDatas().forEach(httpData->{

            try {

                if(httpData instanceof Attribute){
                    Attribute attribute = (Attribute)httpData;
                    httpReq.addParam(attribute.getName(), attribute.getValue());
                    return;
                }

                if(httpData instanceof FileUpload){
                    FileUpload fileUpload = (FileUpload) httpData;

                }

            }catch (Throwable e){
                log.error("", e);

            }

        });


        return httpReq;

    }

    private void assignMessageId(HttpReq httpReq){


    }

    private void transportMetaInfo(HttpReq httpReq, HttpRequest httpRequest){

        QueryStringDecoder queryStringDecoder = new QueryStringDecoder(httpRequest.uri());

        httpReq.setPath(queryStringDecoder.path());
        httpReq.setMethod(httpRequest.method().name());
        httpReq.setVersion(httpRequest.protocolVersion().toString());

        httpRequest.headers().forEach(entry->{
            httpReq.addHeader(entry.getKey(), entry.getValue());

        });

    }

}
